#version 450

layout(location = 1) in vec2 in_texcoord;

struct TextureParam
{
    bool enable;
    float uvRotation;
    vec4 uvTransform;       // x, y -> scale, z, w -> translation
};

vec2 getTextureUV(TextureParam param, vec2 inUV)
{
    vec2 retUV = inUV * param.uvTransform.xy;       // scale
    retUV = vec2(                                   // rotation
        retUV.x * sin(param.uvRotation) + retUV.y * cos(param.uvRotation),
        retUV.y * sin(param.uvRotation) - retUV.x * cos(param.uvRotation)
    );
    inUV = retUV + param.uvTransform.zw;            // translation
    return inUV;
}

layout(set = 0, binding = 0, std140) uniform FrameUBO
{
    mat4 projMatrix;
    mat4 viewMatrix;
    ivec2 resolution;
    uint frameId;
    float time;
} frameUBO;

layout(set = 1, binding = 0, std140) uniform MaterialUBO
{
    vec3 baseColor0;
    vec3 baseColor1;
    float mixValue;
    TextureParam textureParam0;
    TextureParam textureParam1;
} materialUBO;

layout(set = 2, binding = 0) uniform sampler2D texture0;
layout(set = 2, binding = 1) uniform sampler2D texture1;

layout(location = 0) out vec4 out_color;

void main()
{
    vec3 color0 = materialUBO.baseColor0;
    vec3 color1 = materialUBO.baseColor1;

    if (materialUBO.textureParam0.enable)
    {
        TextureParam param = materialUBO.textureParam0;
        param.uvTransform.w = -frameUBO.time;
        color0 = texture(texture0, getTextureUV(param, in_texcoord)).rgb;
    }

    if (materialUBO.textureParam1.enable)
    {
        color1 = texture(texture1, getTextureUV(materialUBO.textureParam1, in_texcoord)).rgb;
    }
    out_color = vec4(mix(color0, color1, materialUBO.mixValue), 1.f);
}